/*
 * Copyright 2014 http://Bither.net
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.bither.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Rect;

public class NativeUtil {

	public static void compressBitmap(Bitmap bit, int quality, String filePath,
			boolean optimize) {
		compressBitmap(bit, quality, filePath, 1, optimize);
	}

	/**
	 * 
	 * 压缩图片
	 * 
	 * @param bit
	 *            源图片
	 * @param quality
	 *            压缩率
	 * @param fileName
	 *            输出文件路径
	 * @param ratio
	 *            输入宽高比 大于1缩小,小于1放大
	 * @param optimize
	 *            如果设置optimize_coding为TRUE，将会使得压缩图像过程中基于图像数据计算哈弗曼表（关于图片压缩中的哈弗曼表，
	 *            请自行查阅相关资料），由于这个计算会显著消耗空间和时间，默认值被设置为FALSE”“
	 *            经我们实测，使用相同的原始图片，分别设置optimize_coding
	 *            =TRUE和FALSE进行压缩，想达到接近的图片质量（用Photoshop
	 *            放大到像素级逐块对比），FALSE时的图片大小大约是TRUE时的5
	 *            -10倍。换句话说，如果我们想在FALSE和TRUE时压缩成相同大小的JPEG
	 *            图片，FALSE的品质将大大逊色于TRUE的（虽然品质很难量化，但我们不妨说成是差5-10倍
	 */
	public static void compressBitmap(Bitmap bit, int quality, String filePath,
			float ratio, boolean optimize) {
		Bitmap result = null;
		float ratioNumber = ratio == 0 ? 1 : ratio;
		result = Bitmap
				.createBitmap((int) ((float) bit.getWidth() / ratioNumber),
						(int) ((float) bit.getHeight() / ratioNumber),
						Config.ARGB_8888);
		Canvas canvas = new Canvas(result);
		Rect rect = new Rect(0, 0,
				(int) ((float) bit.getWidth() / ratioNumber),
				(int) ((float) bit.getHeight() / ratioNumber));
		canvas.drawBitmap(bit, null, rect, null);

		saveBitmap(result, quality, filePath, optimize);
		result.recycle();
	}

	/**
	 * 循环压缩图片
	 * 
	 * @param bmp
	 * @param file
	 */
	public static void compressBmpToFile(Bitmap bmp, File file, int max) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		int options = 100;
		bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
		while (baos.toByteArray().length / 1024 > max) {
			baos.reset();
			bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
			options -= 10;
			if (options == 0)
				break;
		}
		try {
			FileOutputStream fos = new FileOutputStream(file);
			fos.write(baos.toByteArray());
			fos.flush();
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void saveBitmap(Bitmap bit, int quality, String filePath,
			boolean optimize) {
		compressBitmap(bit, bit.getWidth(), bit.getHeight(), quality,
				filePath.getBytes(), optimize);
	}

	private static native String compressBitmap(Bitmap bit, int w, int h,
			int quality, byte[] fileNameBytes, boolean optimize);

	static {
		System.loadLibrary("jpegbither");
		System.loadLibrary("bitherjni");
	}

}
